From 360d5f04c09010bc22197cbce31d46ba3b631b1e Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 22 Jan 2014 16:33:47 +0100 Subject: [PATCH] texthandle: ensure handles are recreated on parent hierarchy changes This ensures the handles come out right even if the parent widget is reparented to a different toplevel. --- gtk/gtktexthandle.c | 65 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/gtk/gtktexthandle.c b/gtk/gtktexthandle.c index 03d54f9386..22c2dff7a3 100644 --- a/gtk/gtktexthandle.c +++ b/gtk/gtktexthandle.c @@ -20,6 +20,7 @@ #include "gtktexthandleprivate.h" #include "gtkmarshalers.h" #include "gtkprivate.h" +#include "gtkwindowprivate.h" #include "gtkintl.h" #include @@ -54,6 +55,7 @@ struct _GtkTextHandlePrivate { HandleWindow windows[2]; GtkWidget *parent; + guint hierarchy_changed_id; guint mode : 2; }; @@ -298,6 +300,63 @@ _gtk_text_handle_update (GtkTextHandle *handle, gtk_widget_hide (handle_window->widget); } +static void +_gtk_text_handle_parent_hierarchy_changed (GtkWidget *widget, + GtkWindow *previous_toplevel, + GtkTextHandle *handle) +{ + GtkWidget *toplevel; + GtkTextHandlePrivate *priv; + + priv = handle->priv; + toplevel = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW); + + if (previous_toplevel && !toplevel) + { + if (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].widget) + { + _gtk_window_remove_popover (GTK_WINDOW (previous_toplevel), + priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].widget); + g_object_unref (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].widget); + priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].widget = NULL; + } + + if (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].widget) + { + _gtk_window_remove_popover (GTK_WINDOW (previous_toplevel), + priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].widget); + g_object_unref (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].widget); + priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].widget = NULL; + } + } +} + +static void +_gtk_text_handle_set_parent (GtkTextHandle *handle, + GtkWidget *parent) +{ + GtkTextHandlePrivate *priv; + + priv = handle->priv; + + if (priv->parent == parent) + return; + + if (priv->parent && priv->hierarchy_changed_id && + g_signal_handler_is_connected (priv->parent, priv->hierarchy_changed_id)) + g_signal_handler_disconnect (priv->parent, priv->hierarchy_changed_id); + + priv->parent = parent; + + if (parent) + { + priv->hierarchy_changed_id = + g_signal_connect (parent, "hierarchy-changed", + G_CALLBACK (_gtk_text_handle_parent_hierarchy_changed), + handle); + } +} + static void gtk_text_handle_finalize (GObject *object) { @@ -305,6 +364,8 @@ gtk_text_handle_finalize (GObject *object) priv = GTK_TEXT_HANDLE (object)->priv; + _gtk_text_handle_set_parent (GTK_TEXT_HANDLE (object), NULL); + /* We sank the references, unref here */ if (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].widget) g_object_unref (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].widget); @@ -321,16 +382,14 @@ gtk_text_handle_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - GtkTextHandlePrivate *priv; GtkTextHandle *handle; handle = GTK_TEXT_HANDLE (object); - priv = handle->priv; switch (prop_id) { case PROP_PARENT: - priv->parent = g_value_get_object (value); + _gtk_text_handle_set_parent (handle, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -- 2.30.2